import javascript

/**
 * A function with `req` and `res` parameters, and hence most likely an
 * HTTP route handler.
 */
class LikelyRouteHandler extends DataFlow::FunctionNode {
  DataFlow::ParameterNode req;
  DataFlow::ParameterNode res;

  LikelyRouteHandler() {
    req = getParameter(0) and req.getName() = "req" and
    res = getParameter(1) and res.getName() = "res"
  }

  /** Gets a method of `res` that sends an HTTP response. */
  string getASendMethodName() {
    // res.send
    result = "send"
    or
    // or a method `m` such that there is an assignment `res.m = res.n` where `n`
    // is already known to be a send method
    exists (DataFlow::PropWrite pwn |
      pwn = res.getAPropertyWrite(result) and
      pwn.getRhs() = getASendMethodReference()
    )
  }

  /** Gets a reference to `res.send` or some other known send method. */
  DataFlow::PropRead getASendMethodReference() {
    result = res.getAPropertyRead(getASendMethodName())
  }

  /** Gets a call to the send method. */
  DataFlow::CallNode getASendMethodCall() {
    result = getASendMethodReference().getACall()
  }
}

// Find `send` calls, which is where the code is sending a reply message.
from LikelyRouteHandler l
select l.getASendMethodCall()
